package com.qg.cyapp.loader;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import android.graphics.Bitmap;
import android.util.Log;

/**
 * 设定内存缓存
 * @author ZZJ
 *
 */
public class MemoryCache {

	private static final String TAG = "MemoryCache";
	
	private Map<String, Bitmap> cache = Collections
			.synchronizedMap(new LinkedHashMap<String, Bitmap>(10, 1.5f, true));
	
	private long size = 0;// 缓存中图片所占用的字节
	
	private long limit = 5000000;// 缓存只能占用的最大堆内存
	
	
	public MemoryCache(){
		//设置最大的内存缓存为程序运行的1/4
		setLimit(Runtime.getRuntime().maxMemory() / 4);
	}
	
	
	/**
	 * 设置当前只能占用的最大堆内存
	 * @param limit
	 */
	public void setLimit(long limit){
		this.limit = limit;
		Log.i(TAG, "MemoryCache will use up to" + limit / 1024. / 1024 + "MB");
	}
	
	/**
	 * 从内存缓存中查找对应的bitmap对象并返回
	 * @param id
	 * @return
	 */
	public Bitmap get(String id){
		try{
			if(!cache.containsKey(id))
				return null;
			return cache.get(id);
		}catch (Exception e){
			return null;
		}
	}
	
	/**
	 * 将bitmap存放到内存缓存中
	 * @param id
	 */
	public void put(String id, Bitmap bitmap){
		try{
			if(cache.containsKey(id))
				size -= getSizeInBytes(cache.get(id));
			cache.put(id, bitmap);
			size += getSizeInBytes(bitmap);
			checkSize();
		}catch (Throwable t){
			t.printStackTrace();
		}
	}
	
	/**
	 * 获取bitmap对象的字节大小
	 * @param bitmap
	 * @return
	 */
	public long getSizeInBytes(Bitmap bitmap){
		if(bitmap == null)
			return 0;
		return bitmap.getRowBytes() * bitmap.getHeight();
	}
	
	/**
	 * 清空图片缓存
	 */
	public void clear(){
		cache.clear();
	}
	
	
	/**
	 * 检测当前所占内存是否超过限定
	 * 若超过则取出最少使用的元素直到限定范围内
	 */
	private void checkSize(){
		Log.i(TAG, "cache size=" + size + " length" + cache.size());
		if(size > limit){
			Iterator<Entry<String, Bitmap>> iter = cache.entrySet().iterator();
			while (iter.hasNext()) {
				Entry<String, Bitmap> entry = iter.next();
				size -= getSizeInBytes(entry.getValue());
				iter.remove();
				if(size <= limit)
					break;
			}
			Log.i(TAG, "Clean cache. New size is " + cache.size());
		}
	}
	
	
}
